Skip to content

Avoid silently wrong results on 10bit CUDA #777

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open

Conversation

NicolasHug
Copy link
Member

Addresses #736 and #598.

Some 10bit videos are properly decoded by NVDEC, but are passed as-is to the NPP color conversion functions, which expect 8bits videos. This results in garbage output. This PR adds a check to prevent such incorrect conversion. It does not add support for 10 bit videos on CUDA. It just avoids silently wrong results.

@NicolasHug NicolasHug added the bug Something isn't working label Jul 13, 2025
@facebook-github-bot facebook-github-bot added the CLA Signed This label is managed by the Meta Open Source bot. label Jul 13, 2025
// AVFrame is on GPU memory. It can be on CPU memory if the video isn't
// supported by NVDEC for whatever reason: NVDEC falls back to CPU decoding in
// this case, and our check fails.
// TODO: we could send the frame back into the CPU path, and rely on
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's create an issue to track.


AVPixelFormat actualFormat =
reinterpret_cast<AVHWFramesContext*>(avFrame->hw_frames_ctx->data)
->sw_format;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I got tripped up reading this because I'm not used to seeing a reinterpret_cast inside of an expression. I think it's easier to read as:

hwFramesCtx = reinterpret_cast<AVHWFramesContext*>(avFrame->hw_frames_ctx->data);
AVPixelFormat actualFormat = hwFramesCtx->sw_format;

Also: TIL that AVBufferRef* is effectively Object* for FFmpeg, and they use it to store lots of different generic stuff.

Copy link
Contributor

@scotts scotts left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wow, great catch!

@pytest.mark.parametrize("asset", (H264_10BITS, H265_10BITS))
def test_10bit_videos_cpu(self, asset):
# This just validates that we can decode 10-bit videos on CPU.
# TODO validate against the ref that the decoded frames are correct
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is required to test that the decoded frames are correct? It seems we would need to check in additional png files from each 10-bit video to the test/resources/, are there other changes needed?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working CLA Signed This label is managed by the Meta Open Source bot.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants